





<!DOCTYPE html>
<html class="writer-html5" lang="zh-CN" >
<head>
  <meta charset="utf-8">
  
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  
  <title>How to Use TVM Pass Instrument &mdash; tvm 0.8.dev1982 文档</title>
  

  
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
  <link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
  <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
  <link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
  <link rel="stylesheet" href="../../_static/gallery.css" type="text/css" />
  <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
  <link rel="stylesheet" href="../../_static/css/tlcpack_theme.css" type="text/css" />

  
  
    <link rel="shortcut icon" href="../../_static/tvm-logo-square.png"/>
  

  
  
  
  
    
      <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
        <script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
        <script src="../../_static/jquery.js"></script>
        <script src="../../_static/underscore.js"></script>
        <script src="../../_static/doctools.js"></script>
        <script src="../../_static/translations.js"></script>
    
    <script type="text/javascript" src="../../_static/js/theme.js"></script>

    
    <script type="text/javascript" src="../../_static/js/tlcpack_theme.js"></script>
    <link rel="index" title="索引" href="../../genindex.html" />
    <link rel="search" title="搜索" href="../../search.html" />
    <link rel="next" title="Bring Your Own Datatypes to TVM" href="bring_your_own_datatypes.html" />
    <link rel="prev" title="How to Use TVM Pass Infra" href="use_pass_infra.html" /> 
</head>

<body class="wy-body-for-nav">

   
  <div class="wy-grid-for-nav">
    
    
<header class="header">
    <div class="innercontainer">
      <div class="headerInner d-flex justify-content-between align-items-center">
          <div class="headerLogo">
               <a href="https://tvm.apache.org/"><img src=https://tvm.apache.org/assets/images/logo.svg alt="logo"></a>
          </div>

          <div id="headMenu" class="headerNav">
            <button type="button" id="closeHeadMenu" class="navCloseBtn"><img src="../../_static/img/close-icon.svg" alt="Close"></button>
             <ul class="nav">
                <li class="nav-item">
                   <a class="nav-link" href=https://tvm.apache.org/community>Community</a>
                </li>
                <li class="nav-item">
                   <a class="nav-link" href=https://tvm.apache.org/download>Download</a>
                </li>
                <li class="nav-item">
                   <a class="nav-link" href=https://tvm.apache.org/vta>VTA</a>
                </li>
                <li class="nav-item">
                   <a class="nav-link" href=https://tvm.apache.org/blog>Blog</a>
                </li>
                <li class="nav-item">
                   <a class="nav-link" href=https://tvm.apache.org/docs>Docs</a>
                </li>
                <li class="nav-item">
                   <a class="nav-link" href=https://tvmconf.org>Conference</a>
                </li>
                <li class="nav-item">
                   <a class="nav-link" href=https://github.com/apache/tvm/>Github</a>
                </li>
                <li class="nav-item">
                   <a class="nav-link" href=https://tvmchinese.github.io/declaration_zh_CN.html>About-Translators</a>
                </li>
             </ul>
               <div class="responsivetlcdropdown">
                 <button type="button" class="btn-link">
                   ASF
                 </button>
                 <ul>
                     <li>
                       <a href=https://apache.org/>Apache Homepage</a>
                     </li>
                     <li>
                       <a href=https://www.apache.org/licenses/>License</a>
                     </li>
                     <li>
                       <a href=https://www.apache.org/foundation/sponsorship.html>Sponsorship</a>
                     </li>
                     <li>
                       <a href=https://www.apache.org/security/>Security</a>
                     </li>
                     <li>
                       <a href=https://www.apache.org/foundation/thanks.html>Thanks</a>
                     </li>
                     <li>
                       <a href=https://www.apache.org/events/current-event>Events</a>
                     </li>
                     <li>
                       <a href=https://www.zhihu.com/column/c_1429578595417563136>Zhihu</a>
                     </li>
                 </ul>
               </div>
          </div>
            <div class="responsiveMenuIcon">
              <button type="button" id="menuBtn" class="btn-menu"><img src="../../_static/img/menu-icon.svg" alt="Menu Icon"></button>
            </div>

            <div class="tlcDropdown">
              <div class="dropdown">
                <button type="button" class="btn-link dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                  ASF
                </button>
                <div class="dropdown-menu dropdown-menu-right">
                  <ul>
                     <li>
                       <a href=https://apache.org/>Apache Homepage</a>
                     </li>
                     <li>
                       <a href=https://www.apache.org/licenses/>License</a>
                     </li>
                     <li>
                       <a href=https://www.apache.org/foundation/sponsorship.html>Sponsorship</a>
                     </li>
                     <li>
                       <a href=https://www.apache.org/security/>Security</a>
                     </li>
                     <li>
                       <a href=https://www.apache.org/foundation/thanks.html>Thanks</a>
                     </li>
                     <li>
                       <a href=https://www.apache.org/events/current-event>Events</a>
                     </li>
                     <li>
                       <a href=https://www.zhihu.com/column/c_1429578595417563136>Zhihu</a>
                     </li>
                  </ul>
                </div>
              </div>
          </div>
       </div>
    </div>
 </header>
 
    <nav data-toggle="wy-nav-shift" class="wy-nav-side fixed">
      <div class="wy-side-scroll">
        <div class="wy-side-nav-search" >
          

          
            <a href="../../index.html">
          

          
            
            <img src="../../_static/tvm-logo-small.png" class="logo" alt="Logo"/>
          
          </a>

          
            
            
                <div class="version">
                  0.8.dev1982
                </div>
            
          

          
<div role="search">
  <form id="rtd-search-form" class="wy-form" action="../../search.html" method="get">
    <input type="text" name="q" placeholder="Search docs" />
    <input type="hidden" name="check_keywords" value="yes" />
    <input type="hidden" name="area" value="default" />
  </form>
</div>

          
        </div>

        
        <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
          
            
            
              
            
            
              <p class="caption" role="heading"><span class="caption-text">如何开始</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../install/index.html">安装 TVM</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../contribute/index.html">贡献者指南</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">用户引导</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../../tutorial/index.html">User Tutorial</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../index.html">How To Guides</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="../compile_models/index.html">编译深度学习模型</a></li>
<li class="toctree-l2"><a class="reference internal" href="../deploy/index.html">TVM 部署模型和集成</a></li>
<li class="toctree-l2"><a class="reference internal" href="../work_with_relay/index.html">Work With Relay</a></li>
<li class="toctree-l2"><a class="reference internal" href="../work_with_schedules/index.html">Work With Tensor Expression and Schedules</a></li>
<li class="toctree-l2"><a class="reference internal" href="../optimize_operators/index.html">优化张量算子</a></li>
<li class="toctree-l2"><a class="reference internal" href="../tune_with_autotvm/index.html">Auto-Tune with Templates and AutoTVM</a></li>
<li class="toctree-l2"><a class="reference internal" href="../tune_with_autoscheduler/index.html">Use AutoScheduler for Template-Free Scheduling</a></li>
<li class="toctree-l2"><a class="reference internal" href="../work_with_microtvm/index.html">Work With microTVM</a></li>
<li class="toctree-l2 current"><a class="reference internal" href="index.html">Extend TVM</a><ul class="current">
<li class="toctree-l3"><a class="reference internal" href="low_level_custom_pass.html">编写自定义通行证</a></li>
<li class="toctree-l3"><a class="reference internal" href="use_pass_infra.html">How to Use TVM Pass Infra</a></li>
<li class="toctree-l3 current"><a class="current reference internal" href="#">How to Use TVM Pass Instrument</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#create-an-example-relay-program">Create An Example Relay Program</a></li>
<li class="toctree-l4"><a class="reference internal" href="#create-passcontext-with-instruments">Create PassContext With Instruments</a></li>
<li class="toctree-l4"><a class="reference internal" href="#use-current-passcontext-with-instruments">Use Current PassContext With Instruments</a></li>
<li class="toctree-l4"><a class="reference internal" href="#create-customized-instrument-class">Create Customized Instrument Class</a></li>
<li class="toctree-l4"><a class="reference internal" href="#apply-passes-and-multiple-instrument-classes">Apply Passes and Multiple Instrument Classes</a></li>
<li class="toctree-l4"><a class="reference internal" href="#exception-handling">Exception Handling</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="bring_your_own_datatypes.html">Bring Your Own Datatypes to TVM</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../profile/index.html">Profile Models</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../errors.html">Handle TVM Errors</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../faq.html">常见提问</a></li>
</ul>
</li>
</ul>
<p class="caption" role="heading"><span class="caption-text">开发者引导</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../dev/tutorial/index.html">Developer Tutorial</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../dev/how_to/how_to.html">开发者指南</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">架构指南</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../arch/index.html">Design and Architecture</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">主题引导</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../topic/microtvm/index.html">microTVM：裸机使用TVM</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../topic/vta/index.html">VTA: Versatile Tensor Accelerator</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">参考指南</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../reference/langref/index.html">语言参考</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../reference/api/python/index.html">Python API</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../reference/api/links.html">Other APIs</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../reference/publications.html">Publications</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../genindex.html">索引</a></li>
</ul>

            
          
        </div>
        
      </div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
      
      <nav class="wy-nav-top" aria-label="top navigation" data-toggle="wy-nav-top">
        
            <div class="togglemenu">

            </div>
            <div class="nav-content">
              <!-- tvm -->
              Table of content
            </div>
        
      </nav>


      <div class="wy-nav-content">
        
        <div class="rst-content">
        

          




















<div role="navigation" aria-label="breadcrumbs navigation">

  <ul class="wy-breadcrumbs">
    
      <li><a href="../../index.html">Docs</a> <span class="br-arrow">></span></li>
        
          <li><a href="../index.html">How To Guides</a> <span class="br-arrow">></span></li>
        
          <li><a href="index.html">Extend TVM</a> <span class="br-arrow">></span></li>
        
      <li>How to Use TVM Pass Instrument</li>
    
    
      <li class="wy-breadcrumbs-aside">
        
            
            <a href="../../_sources/how_to/extend_tvm/use_pass_instrument.rst.txt" rel="nofollow"> <img src="../../_static//img/source.svg" alt="viewsource"/></a>
          
        
      </li>
    
  </ul>

  
  <hr/>
</div>
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
           <div itemprop="articleBody">
            
  <div class="sphx-glr-download-link-note admonition note">
<p class="admonition-title">注解</p>
<p>Click <a class="reference internal" href="#sphx-glr-download-how-to-extend-tvm-use-pass-instrument-py"><span class="std std-ref">here</span></a> to download the full example code</p>
</div>
<div class="sphx-glr-example-title section" id="how-to-use-tvm-pass-instrument">
<span id="tutorial-use-pass-instrument"></span><span id="sphx-glr-how-to-extend-tvm-use-pass-instrument-py"></span><h1>How to Use TVM Pass Instrument<a class="headerlink" href="#how-to-use-tvm-pass-instrument" title="永久链接至标题">¶</a></h1>
<p><strong>Author</strong>: <a class="reference external" href="https://github.com/chiwwang">Chi-Wei Wang</a></p>
<p>As more and more passes are implemented, it becomes useful to instrument
pass execution, analyze per-pass effects, and observe various events.</p>
<p>We can instrument passes by providing a list of <a class="reference internal" href="../../reference/api/python/ir.html#tvm.instrument.PassInstrument" title="tvm.ir.instrument.PassInstrument"><code class="xref py py-class docutils literal notranslate"><span class="pre">tvm.ir.instrument.PassInstrument</span></code></a>
instances to <a class="reference internal" href="../../reference/api/python/ir.html#tvm.transform.PassContext" title="tvm.transform.PassContext"><code class="xref py py-class docutils literal notranslate"><span class="pre">tvm.transform.PassContext</span></code></a>. We provide a pass instrument
for collecting timing information (<a class="reference internal" href="../../reference/api/python/ir.html#tvm.instrument.PassTimingInstrument" title="tvm.ir.instrument.PassTimingInstrument"><code class="xref py py-class docutils literal notranslate"><span class="pre">tvm.ir.instrument.PassTimingInstrument</span></code></a>),
but an extension mechanism is available via the <a class="reference internal" href="../../reference/api/python/ir.html#tvm.instrument.pass_instrument" title="tvm.instrument.pass_instrument"><code class="xref py py-func docutils literal notranslate"><span class="pre">tvm.instrument.pass_instrument()</span></code></a> decorator.</p>
<p>This tutorial demostrates how developers can use <code class="docutils literal notranslate"><span class="pre">PassContext</span></code> to instrument
passes. Please also refer to the <a class="reference internal" href="../../arch/pass_infra.html#pass-infra"><span class="std std-ref">Pass Infrastructure</span></a>.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">tvm</span>
<span class="kn">import</span> <span class="nn">tvm.relay</span> <span class="k">as</span> <span class="nn">relay</span>
<span class="kn">from</span> <span class="nn">tvm.relay.testing</span> <span class="k">import</span> <span class="n">resnet</span>
<span class="kn">from</span> <span class="nn">tvm.contrib.download</span> <span class="k">import</span> <span class="n">download_testdata</span>
<span class="kn">from</span> <span class="nn">tvm.relay.build_module</span> <span class="k">import</span> <span class="n">bind_params_by_name</span>
<span class="kn">from</span> <span class="nn">tvm.ir.instrument</span> <span class="k">import</span> <span class="p">(</span>
    <span class="n">PassTimingInstrument</span><span class="p">,</span>
    <span class="n">pass_instrument</span><span class="p">,</span>
<span class="p">)</span>
</pre></div>
</div>
<div class="section" id="create-an-example-relay-program">
<h2>Create An Example Relay Program<a class="headerlink" href="#create-an-example-relay-program" title="永久链接至标题">¶</a></h2>
<p>We use pre-defined resnet-18 network in Relay.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">batch_size</span> <span class="o">=</span> <span class="mi">1</span>
<span class="n">num_of_image_class</span> <span class="o">=</span> <span class="mi">1000</span>
<span class="n">image_shape</span> <span class="o">=</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">224</span><span class="p">,</span> <span class="mi">224</span><span class="p">)</span>
<span class="n">output_shape</span> <span class="o">=</span> <span class="p">(</span><span class="n">batch_size</span><span class="p">,</span> <span class="n">num_of_image_class</span><span class="p">)</span>
<span class="n">relay_mod</span><span class="p">,</span> <span class="n">relay_params</span> <span class="o">=</span> <span class="n">resnet</span><span class="o">.</span><span class="n">get_workload</span><span class="p">(</span><span class="n">num_layers</span><span class="o">=</span><span class="mi">18</span><span class="p">,</span> <span class="n">batch_size</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">image_shape</span><span class="o">=</span><span class="n">image_shape</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Printing the IR module...&quot;</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">relay_mod</span><span class="o">.</span><span class="n">astext</span><span class="p">(</span><span class="n">show_meta_data</span><span class="o">=</span><span class="kc">False</span><span class="p">))</span>
</pre></div>
</div>
<p class="sphx-glr-script-out">输出:</p>
<div class="sphx-glr-script-out highlight-none notranslate"><div class="highlight"><pre><span></span>Printing the IR module...
#[version = &quot;0.0.5&quot;]
def @main(%data: Tensor[(1, 3, 224, 224), float32], %bn_data_gamma: Tensor[(3), float32], %bn_data_beta: Tensor[(3), float32], %bn_data_moving_mean: Tensor[(3), float32], %bn_data_moving_var: Tensor[(3), float32], %conv0_weight: Tensor[(64, 3, 7, 7), float32], %bn0_gamma: Tensor[(64), float32], %bn0_beta: Tensor[(64), float32], %bn0_moving_mean: Tensor[(64), float32], %bn0_moving_var: Tensor[(64), float32], %stage1_unit1_bn1_gamma: Tensor[(64), float32], %stage1_unit1_bn1_beta: Tensor[(64), float32], %stage1_unit1_bn1_moving_mean: Tensor[(64), float32], %stage1_unit1_bn1_moving_var: Tensor[(64), float32], %stage1_unit1_conv1_weight: Tensor[(64, 64, 3, 3), float32], %stage1_unit1_bn2_gamma: Tensor[(64), float32], %stage1_unit1_bn2_beta: Tensor[(64), float32], %stage1_unit1_bn2_moving_mean: Tensor[(64), float32], %stage1_unit1_bn2_moving_var: Tensor[(64), float32], %stage1_unit1_conv2_weight: Tensor[(64, 64, 3, 3), float32], %stage1_unit1_sc_weight: Tensor[(64, 64, 1, 1), float32], %stage1_unit2_bn1_gamma: Tensor[(64), float32], %stage1_unit2_bn1_beta: Tensor[(64), float32], %stage1_unit2_bn1_moving_mean: Tensor[(64), float32], %stage1_unit2_bn1_moving_var: Tensor[(64), float32], %stage1_unit2_conv1_weight: Tensor[(64, 64, 3, 3), float32], %stage1_unit2_bn2_gamma: Tensor[(64), float32], %stage1_unit2_bn2_beta: Tensor[(64), float32], %stage1_unit2_bn2_moving_mean: Tensor[(64), float32], %stage1_unit2_bn2_moving_var: Tensor[(64), float32], %stage1_unit2_conv2_weight: Tensor[(64, 64, 3, 3), float32], %stage2_unit1_bn1_gamma: Tensor[(64), float32], %stage2_unit1_bn1_beta: Tensor[(64), float32], %stage2_unit1_bn1_moving_mean: Tensor[(64), float32], %stage2_unit1_bn1_moving_var: Tensor[(64), float32], %stage2_unit1_conv1_weight: Tensor[(128, 64, 3, 3), float32], %stage2_unit1_bn2_gamma: Tensor[(128), float32], %stage2_unit1_bn2_beta: Tensor[(128), float32], %stage2_unit1_bn2_moving_mean: Tensor[(128), float32], %stage2_unit1_bn2_moving_var: Tensor[(128), float32], %stage2_unit1_conv2_weight: Tensor[(128, 128, 3, 3), float32], %stage2_unit1_sc_weight: Tensor[(128, 64, 1, 1), float32], %stage2_unit2_bn1_gamma: Tensor[(128), float32], %stage2_unit2_bn1_beta: Tensor[(128), float32], %stage2_unit2_bn1_moving_mean: Tensor[(128), float32], %stage2_unit2_bn1_moving_var: Tensor[(128), float32], %stage2_unit2_conv1_weight: Tensor[(128, 128, 3, 3), float32], %stage2_unit2_bn2_gamma: Tensor[(128), float32], %stage2_unit2_bn2_beta: Tensor[(128), float32], %stage2_unit2_bn2_moving_mean: Tensor[(128), float32], %stage2_unit2_bn2_moving_var: Tensor[(128), float32], %stage2_unit2_conv2_weight: Tensor[(128, 128, 3, 3), float32], %stage3_unit1_bn1_gamma: Tensor[(128), float32], %stage3_unit1_bn1_beta: Tensor[(128), float32], %stage3_unit1_bn1_moving_mean: Tensor[(128), float32], %stage3_unit1_bn1_moving_var: Tensor[(128), float32], %stage3_unit1_conv1_weight: Tensor[(256, 128, 3, 3), float32], %stage3_unit1_bn2_gamma: Tensor[(256), float32], %stage3_unit1_bn2_beta: Tensor[(256), float32], %stage3_unit1_bn2_moving_mean: Tensor[(256), float32], %stage3_unit1_bn2_moving_var: Tensor[(256), float32], %stage3_unit1_conv2_weight: Tensor[(256, 256, 3, 3), float32], %stage3_unit1_sc_weight: Tensor[(256, 128, 1, 1), float32], %stage3_unit2_bn1_gamma: Tensor[(256), float32], %stage3_unit2_bn1_beta: Tensor[(256), float32], %stage3_unit2_bn1_moving_mean: Tensor[(256), float32], %stage3_unit2_bn1_moving_var: Tensor[(256), float32], %stage3_unit2_conv1_weight: Tensor[(256, 256, 3, 3), float32], %stage3_unit2_bn2_gamma: Tensor[(256), float32], %stage3_unit2_bn2_beta: Tensor[(256), float32], %stage3_unit2_bn2_moving_mean: Tensor[(256), float32], %stage3_unit2_bn2_moving_var: Tensor[(256), float32], %stage3_unit2_conv2_weight: Tensor[(256, 256, 3, 3), float32], %stage4_unit1_bn1_gamma: Tensor[(256), float32], %stage4_unit1_bn1_beta: Tensor[(256), float32], %stage4_unit1_bn1_moving_mean: Tensor[(256), float32], %stage4_unit1_bn1_moving_var: Tensor[(256), float32], %stage4_unit1_conv1_weight: Tensor[(512, 256, 3, 3), float32], %stage4_unit1_bn2_gamma: Tensor[(512), float32], %stage4_unit1_bn2_beta: Tensor[(512), float32], %stage4_unit1_bn2_moving_mean: Tensor[(512), float32], %stage4_unit1_bn2_moving_var: Tensor[(512), float32], %stage4_unit1_conv2_weight: Tensor[(512, 512, 3, 3), float32], %stage4_unit1_sc_weight: Tensor[(512, 256, 1, 1), float32], %stage4_unit2_bn1_gamma: Tensor[(512), float32], %stage4_unit2_bn1_beta: Tensor[(512), float32], %stage4_unit2_bn1_moving_mean: Tensor[(512), float32], %stage4_unit2_bn1_moving_var: Tensor[(512), float32], %stage4_unit2_conv1_weight: Tensor[(512, 512, 3, 3), float32], %stage4_unit2_bn2_gamma: Tensor[(512), float32], %stage4_unit2_bn2_beta: Tensor[(512), float32], %stage4_unit2_bn2_moving_mean: Tensor[(512), float32], %stage4_unit2_bn2_moving_var: Tensor[(512), float32], %stage4_unit2_conv2_weight: Tensor[(512, 512, 3, 3), float32], %bn1_gamma: Tensor[(512), float32], %bn1_beta: Tensor[(512), float32], %bn1_moving_mean: Tensor[(512), float32], %bn1_moving_var: Tensor[(512), float32], %fc1_weight: Tensor[(1000, 512), float32], %fc1_bias: Tensor[(1000), float32]) -&gt; Tensor[(1, 1000), float32] {
  %0 = nn.batch_norm(%data, %bn_data_gamma, %bn_data_beta, %bn_data_moving_mean, %bn_data_moving_var, epsilon=2e-05f, scale=False) /* ty=(Tensor[(1, 3, 224, 224), float32], Tensor[(3), float32], Tensor[(3), float32]) */;
  %1 = %0.0;
  %2 = nn.conv2d(%1, %conv0_weight, strides=[2, 2], padding=[3, 3, 3, 3], channels=64, kernel_size=[7, 7]) /* ty=Tensor[(1, 64, 112, 112), float32] */;
  %3 = nn.batch_norm(%2, %bn0_gamma, %bn0_beta, %bn0_moving_mean, %bn0_moving_var, epsilon=2e-05f) /* ty=(Tensor[(1, 64, 112, 112), float32], Tensor[(64), float32], Tensor[(64), float32]) */;
  %4 = %3.0;
  %5 = nn.relu(%4) /* ty=Tensor[(1, 64, 112, 112), float32] */;
  %6 = nn.max_pool2d(%5, pool_size=[3, 3], strides=[2, 2], padding=[1, 1, 1, 1]) /* ty=Tensor[(1, 64, 56, 56), float32] */;
  %7 = nn.batch_norm(%6, %stage1_unit1_bn1_gamma, %stage1_unit1_bn1_beta, %stage1_unit1_bn1_moving_mean, %stage1_unit1_bn1_moving_var, epsilon=2e-05f) /* ty=(Tensor[(1, 64, 56, 56), float32], Tensor[(64), float32], Tensor[(64), float32]) */;
  %8 = %7.0;
  %9 = nn.relu(%8) /* ty=Tensor[(1, 64, 56, 56), float32] */;
  %10 = nn.conv2d(%9, %stage1_unit1_conv1_weight, padding=[1, 1, 1, 1], channels=64, kernel_size=[3, 3]) /* ty=Tensor[(1, 64, 56, 56), float32] */;
  %11 = nn.batch_norm(%10, %stage1_unit1_bn2_gamma, %stage1_unit1_bn2_beta, %stage1_unit1_bn2_moving_mean, %stage1_unit1_bn2_moving_var, epsilon=2e-05f) /* ty=(Tensor[(1, 64, 56, 56), float32], Tensor[(64), float32], Tensor[(64), float32]) */;
  %12 = %11.0;
  %13 = nn.relu(%12) /* ty=Tensor[(1, 64, 56, 56), float32] */;
  %14 = nn.conv2d(%13, %stage1_unit1_conv2_weight, padding=[1, 1, 1, 1], channels=64, kernel_size=[3, 3]) /* ty=Tensor[(1, 64, 56, 56), float32] */;
  %15 = nn.conv2d(%9, %stage1_unit1_sc_weight, padding=[0, 0, 0, 0], channels=64, kernel_size=[1, 1]) /* ty=Tensor[(1, 64, 56, 56), float32] */;
  %16 = add(%14, %15) /* ty=Tensor[(1, 64, 56, 56), float32] */;
  %17 = nn.batch_norm(%16, %stage1_unit2_bn1_gamma, %stage1_unit2_bn1_beta, %stage1_unit2_bn1_moving_mean, %stage1_unit2_bn1_moving_var, epsilon=2e-05f) /* ty=(Tensor[(1, 64, 56, 56), float32], Tensor[(64), float32], Tensor[(64), float32]) */;
  %18 = %17.0;
  %19 = nn.relu(%18) /* ty=Tensor[(1, 64, 56, 56), float32] */;
  %20 = nn.conv2d(%19, %stage1_unit2_conv1_weight, padding=[1, 1, 1, 1], channels=64, kernel_size=[3, 3]) /* ty=Tensor[(1, 64, 56, 56), float32] */;
  %21 = nn.batch_norm(%20, %stage1_unit2_bn2_gamma, %stage1_unit2_bn2_beta, %stage1_unit2_bn2_moving_mean, %stage1_unit2_bn2_moving_var, epsilon=2e-05f) /* ty=(Tensor[(1, 64, 56, 56), float32], Tensor[(64), float32], Tensor[(64), float32]) */;
  %22 = %21.0;
  %23 = nn.relu(%22) /* ty=Tensor[(1, 64, 56, 56), float32] */;
  %24 = nn.conv2d(%23, %stage1_unit2_conv2_weight, padding=[1, 1, 1, 1], channels=64, kernel_size=[3, 3]) /* ty=Tensor[(1, 64, 56, 56), float32] */;
  %25 = add(%24, %16) /* ty=Tensor[(1, 64, 56, 56), float32] */;
  %26 = nn.batch_norm(%25, %stage2_unit1_bn1_gamma, %stage2_unit1_bn1_beta, %stage2_unit1_bn1_moving_mean, %stage2_unit1_bn1_moving_var, epsilon=2e-05f) /* ty=(Tensor[(1, 64, 56, 56), float32], Tensor[(64), float32], Tensor[(64), float32]) */;
  %27 = %26.0;
  %28 = nn.relu(%27) /* ty=Tensor[(1, 64, 56, 56), float32] */;
  %29 = nn.conv2d(%28, %stage2_unit1_conv1_weight, strides=[2, 2], padding=[1, 1, 1, 1], channels=128, kernel_size=[3, 3]) /* ty=Tensor[(1, 128, 28, 28), float32] */;
  %30 = nn.batch_norm(%29, %stage2_unit1_bn2_gamma, %stage2_unit1_bn2_beta, %stage2_unit1_bn2_moving_mean, %stage2_unit1_bn2_moving_var, epsilon=2e-05f) /* ty=(Tensor[(1, 128, 28, 28), float32], Tensor[(128), float32], Tensor[(128), float32]) */;
  %31 = %30.0;
  %32 = nn.relu(%31) /* ty=Tensor[(1, 128, 28, 28), float32] */;
  %33 = nn.conv2d(%32, %stage2_unit1_conv2_weight, padding=[1, 1, 1, 1], channels=128, kernel_size=[3, 3]) /* ty=Tensor[(1, 128, 28, 28), float32] */;
  %34 = nn.conv2d(%28, %stage2_unit1_sc_weight, strides=[2, 2], padding=[0, 0, 0, 0], channels=128, kernel_size=[1, 1]) /* ty=Tensor[(1, 128, 28, 28), float32] */;
  %35 = add(%33, %34) /* ty=Tensor[(1, 128, 28, 28), float32] */;
  %36 = nn.batch_norm(%35, %stage2_unit2_bn1_gamma, %stage2_unit2_bn1_beta, %stage2_unit2_bn1_moving_mean, %stage2_unit2_bn1_moving_var, epsilon=2e-05f) /* ty=(Tensor[(1, 128, 28, 28), float32], Tensor[(128), float32], Tensor[(128), float32]) */;
  %37 = %36.0;
  %38 = nn.relu(%37) /* ty=Tensor[(1, 128, 28, 28), float32] */;
  %39 = nn.conv2d(%38, %stage2_unit2_conv1_weight, padding=[1, 1, 1, 1], channels=128, kernel_size=[3, 3]) /* ty=Tensor[(1, 128, 28, 28), float32] */;
  %40 = nn.batch_norm(%39, %stage2_unit2_bn2_gamma, %stage2_unit2_bn2_beta, %stage2_unit2_bn2_moving_mean, %stage2_unit2_bn2_moving_var, epsilon=2e-05f) /* ty=(Tensor[(1, 128, 28, 28), float32], Tensor[(128), float32], Tensor[(128), float32]) */;
  %41 = %40.0;
  %42 = nn.relu(%41) /* ty=Tensor[(1, 128, 28, 28), float32] */;
  %43 = nn.conv2d(%42, %stage2_unit2_conv2_weight, padding=[1, 1, 1, 1], channels=128, kernel_size=[3, 3]) /* ty=Tensor[(1, 128, 28, 28), float32] */;
  %44 = add(%43, %35) /* ty=Tensor[(1, 128, 28, 28), float32] */;
  %45 = nn.batch_norm(%44, %stage3_unit1_bn1_gamma, %stage3_unit1_bn1_beta, %stage3_unit1_bn1_moving_mean, %stage3_unit1_bn1_moving_var, epsilon=2e-05f) /* ty=(Tensor[(1, 128, 28, 28), float32], Tensor[(128), float32], Tensor[(128), float32]) */;
  %46 = %45.0;
  %47 = nn.relu(%46) /* ty=Tensor[(1, 128, 28, 28), float32] */;
  %48 = nn.conv2d(%47, %stage3_unit1_conv1_weight, strides=[2, 2], padding=[1, 1, 1, 1], channels=256, kernel_size=[3, 3]) /* ty=Tensor[(1, 256, 14, 14), float32] */;
  %49 = nn.batch_norm(%48, %stage3_unit1_bn2_gamma, %stage3_unit1_bn2_beta, %stage3_unit1_bn2_moving_mean, %stage3_unit1_bn2_moving_var, epsilon=2e-05f) /* ty=(Tensor[(1, 256, 14, 14), float32], Tensor[(256), float32], Tensor[(256), float32]) */;
  %50 = %49.0;
  %51 = nn.relu(%50) /* ty=Tensor[(1, 256, 14, 14), float32] */;
  %52 = nn.conv2d(%51, %stage3_unit1_conv2_weight, padding=[1, 1, 1, 1], channels=256, kernel_size=[3, 3]) /* ty=Tensor[(1, 256, 14, 14), float32] */;
  %53 = nn.conv2d(%47, %stage3_unit1_sc_weight, strides=[2, 2], padding=[0, 0, 0, 0], channels=256, kernel_size=[1, 1]) /* ty=Tensor[(1, 256, 14, 14), float32] */;
  %54 = add(%52, %53) /* ty=Tensor[(1, 256, 14, 14), float32] */;
  %55 = nn.batch_norm(%54, %stage3_unit2_bn1_gamma, %stage3_unit2_bn1_beta, %stage3_unit2_bn1_moving_mean, %stage3_unit2_bn1_moving_var, epsilon=2e-05f) /* ty=(Tensor[(1, 256, 14, 14), float32], Tensor[(256), float32], Tensor[(256), float32]) */;
  %56 = %55.0;
  %57 = nn.relu(%56) /* ty=Tensor[(1, 256, 14, 14), float32] */;
  %58 = nn.conv2d(%57, %stage3_unit2_conv1_weight, padding=[1, 1, 1, 1], channels=256, kernel_size=[3, 3]) /* ty=Tensor[(1, 256, 14, 14), float32] */;
  %59 = nn.batch_norm(%58, %stage3_unit2_bn2_gamma, %stage3_unit2_bn2_beta, %stage3_unit2_bn2_moving_mean, %stage3_unit2_bn2_moving_var, epsilon=2e-05f) /* ty=(Tensor[(1, 256, 14, 14), float32], Tensor[(256), float32], Tensor[(256), float32]) */;
  %60 = %59.0;
  %61 = nn.relu(%60) /* ty=Tensor[(1, 256, 14, 14), float32] */;
  %62 = nn.conv2d(%61, %stage3_unit2_conv2_weight, padding=[1, 1, 1, 1], channels=256, kernel_size=[3, 3]) /* ty=Tensor[(1, 256, 14, 14), float32] */;
  %63 = add(%62, %54) /* ty=Tensor[(1, 256, 14, 14), float32] */;
  %64 = nn.batch_norm(%63, %stage4_unit1_bn1_gamma, %stage4_unit1_bn1_beta, %stage4_unit1_bn1_moving_mean, %stage4_unit1_bn1_moving_var, epsilon=2e-05f) /* ty=(Tensor[(1, 256, 14, 14), float32], Tensor[(256), float32], Tensor[(256), float32]) */;
  %65 = %64.0;
  %66 = nn.relu(%65) /* ty=Tensor[(1, 256, 14, 14), float32] */;
  %67 = nn.conv2d(%66, %stage4_unit1_conv1_weight, strides=[2, 2], padding=[1, 1, 1, 1], channels=512, kernel_size=[3, 3]) /* ty=Tensor[(1, 512, 7, 7), float32] */;
  %68 = nn.batch_norm(%67, %stage4_unit1_bn2_gamma, %stage4_unit1_bn2_beta, %stage4_unit1_bn2_moving_mean, %stage4_unit1_bn2_moving_var, epsilon=2e-05f) /* ty=(Tensor[(1, 512, 7, 7), float32], Tensor[(512), float32], Tensor[(512), float32]) */;
  %69 = %68.0;
  %70 = nn.relu(%69) /* ty=Tensor[(1, 512, 7, 7), float32] */;
  %71 = nn.conv2d(%70, %stage4_unit1_conv2_weight, padding=[1, 1, 1, 1], channels=512, kernel_size=[3, 3]) /* ty=Tensor[(1, 512, 7, 7), float32] */;
  %72 = nn.conv2d(%66, %stage4_unit1_sc_weight, strides=[2, 2], padding=[0, 0, 0, 0], channels=512, kernel_size=[1, 1]) /* ty=Tensor[(1, 512, 7, 7), float32] */;
  %73 = add(%71, %72) /* ty=Tensor[(1, 512, 7, 7), float32] */;
  %74 = nn.batch_norm(%73, %stage4_unit2_bn1_gamma, %stage4_unit2_bn1_beta, %stage4_unit2_bn1_moving_mean, %stage4_unit2_bn1_moving_var, epsilon=2e-05f) /* ty=(Tensor[(1, 512, 7, 7), float32], Tensor[(512), float32], Tensor[(512), float32]) */;
  %75 = %74.0;
  %76 = nn.relu(%75) /* ty=Tensor[(1, 512, 7, 7), float32] */;
  %77 = nn.conv2d(%76, %stage4_unit2_conv1_weight, padding=[1, 1, 1, 1], channels=512, kernel_size=[3, 3]) /* ty=Tensor[(1, 512, 7, 7), float32] */;
  %78 = nn.batch_norm(%77, %stage4_unit2_bn2_gamma, %stage4_unit2_bn2_beta, %stage4_unit2_bn2_moving_mean, %stage4_unit2_bn2_moving_var, epsilon=2e-05f) /* ty=(Tensor[(1, 512, 7, 7), float32], Tensor[(512), float32], Tensor[(512), float32]) */;
  %79 = %78.0;
  %80 = nn.relu(%79) /* ty=Tensor[(1, 512, 7, 7), float32] */;
  %81 = nn.conv2d(%80, %stage4_unit2_conv2_weight, padding=[1, 1, 1, 1], channels=512, kernel_size=[3, 3]) /* ty=Tensor[(1, 512, 7, 7), float32] */;
  %82 = add(%81, %73) /* ty=Tensor[(1, 512, 7, 7), float32] */;
  %83 = nn.batch_norm(%82, %bn1_gamma, %bn1_beta, %bn1_moving_mean, %bn1_moving_var, epsilon=2e-05f) /* ty=(Tensor[(1, 512, 7, 7), float32], Tensor[(512), float32], Tensor[(512), float32]) */;
  %84 = %83.0;
  %85 = nn.relu(%84) /* ty=Tensor[(1, 512, 7, 7), float32] */;
  %86 = nn.global_avg_pool2d(%85) /* ty=Tensor[(1, 512, 1, 1), float32] */;
  %87 = nn.batch_flatten(%86) /* ty=Tensor[(1, 512), float32] */;
  %88 = nn.dense(%87, %fc1_weight, units=1000) /* ty=Tensor[(1, 1000), float32] */;
  %89 = nn.bias_add(%88, %fc1_bias, axis=-1) /* ty=Tensor[(1, 1000), float32] */;
  nn.softmax(%89) /* ty=Tensor[(1, 1000), float32] */
}
</pre></div>
</div>
</div>
<div class="section" id="create-passcontext-with-instruments">
<h2>Create PassContext With Instruments<a class="headerlink" href="#create-passcontext-with-instruments" title="永久链接至标题">¶</a></h2>
<p>To run all passes with an instrument, pass it via the <code class="docutils literal notranslate"><span class="pre">instruments</span></code> argument to
the <code class="docutils literal notranslate"><span class="pre">PassContext</span></code> constructor. A built-in <code class="docutils literal notranslate"><span class="pre">PassTimingInstrument</span></code> is used to
profile the execution time of each passes.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">timing_inst</span> <span class="o">=</span> <span class="n">PassTimingInstrument</span><span class="p">()</span>
<span class="k">with</span> <span class="n">tvm</span><span class="o">.</span><span class="n">transform</span><span class="o">.</span><span class="n">PassContext</span><span class="p">(</span><span class="n">instruments</span><span class="o">=</span><span class="p">[</span><span class="n">timing_inst</span><span class="p">]):</span>
    <span class="n">relay_mod</span> <span class="o">=</span> <span class="n">relay</span><span class="o">.</span><span class="n">transform</span><span class="o">.</span><span class="n">InferType</span><span class="p">()(</span><span class="n">relay_mod</span><span class="p">)</span>
    <span class="n">relay_mod</span> <span class="o">=</span> <span class="n">relay</span><span class="o">.</span><span class="n">transform</span><span class="o">.</span><span class="n">FoldScaleAxis</span><span class="p">()(</span><span class="n">relay_mod</span><span class="p">)</span>
    <span class="c1"># before exiting the context, get profile results.</span>
    <span class="n">profiles</span> <span class="o">=</span> <span class="n">timing_inst</span><span class="o">.</span><span class="n">render</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Printing results of timing profile...&quot;</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">profiles</span><span class="p">)</span>
</pre></div>
</div>
<p class="sphx-glr-script-out">输出:</p>
<div class="sphx-glr-script-out highlight-none notranslate"><div class="highlight"><pre><span></span>Printing results of timing profile...
InferType: 4340us [4340us] (45.31%; 45.31%)
FoldScaleAxis: 5239us [2us] (54.69%; 54.69%)
        FoldConstant: 5237us [1069us] (54.67%; 99.96%)
                InferType: 4168us [4168us] (43.52%; 79.59%)
</pre></div>
</div>
</div>
<div class="section" id="use-current-passcontext-with-instruments">
<h2>Use Current PassContext With Instruments<a class="headerlink" href="#use-current-passcontext-with-instruments" title="永久链接至标题">¶</a></h2>
<p>One can also use the current <code class="docutils literal notranslate"><span class="pre">PassContext</span></code> and register
<code class="docutils literal notranslate"><span class="pre">PassInstrument</span></code> instances by <code class="docutils literal notranslate"><span class="pre">override_instruments</span></code> method.
Note that <code class="docutils literal notranslate"><span class="pre">override_instruments</span></code> executes <code class="docutils literal notranslate"><span class="pre">exit_pass_ctx</span></code> method
if any instrument already exists. Then it switches to new instruments
and calls <code class="docutils literal notranslate"><span class="pre">enter_pass_ctx</span></code> method of new instruments.
Refer to following sections and <a class="reference internal" href="../../reference/api/python/ir.html#tvm.instrument.pass_instrument" title="tvm.instrument.pass_instrument"><code class="xref py py-func docutils literal notranslate"><span class="pre">tvm.instrument.pass_instrument()</span></code></a> for these methods.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">cur_pass_ctx</span> <span class="o">=</span> <span class="n">tvm</span><span class="o">.</span><span class="n">transform</span><span class="o">.</span><span class="n">PassContext</span><span class="o">.</span><span class="n">current</span><span class="p">()</span>
<span class="n">cur_pass_ctx</span><span class="o">.</span><span class="n">override_instruments</span><span class="p">([</span><span class="n">timing_inst</span><span class="p">])</span>
<span class="n">relay_mod</span> <span class="o">=</span> <span class="n">relay</span><span class="o">.</span><span class="n">transform</span><span class="o">.</span><span class="n">InferType</span><span class="p">()(</span><span class="n">relay_mod</span><span class="p">)</span>
<span class="n">relay_mod</span> <span class="o">=</span> <span class="n">relay</span><span class="o">.</span><span class="n">transform</span><span class="o">.</span><span class="n">FoldScaleAxis</span><span class="p">()(</span><span class="n">relay_mod</span><span class="p">)</span>
<span class="n">profiles</span> <span class="o">=</span> <span class="n">timing_inst</span><span class="o">.</span><span class="n">render</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Printing results of timing profile...&quot;</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">profiles</span><span class="p">)</span>
</pre></div>
</div>
<p class="sphx-glr-script-out">输出:</p>
<div class="sphx-glr-script-out highlight-none notranslate"><div class="highlight"><pre><span></span>Printing results of timing profile...
InferType: 3774us [3774us] (44.46%; 44.46%)
FoldScaleAxis: 4716us [2us] (55.54%; 55.54%)
        FoldConstant: 4714us [1051us] (55.52%; 99.97%)
                InferType: 3663us [3663us] (43.15%; 77.70%)
</pre></div>
</div>
<p>Register empty list to clear existing instruments.</p>
<p>Note that <code class="docutils literal notranslate"><span class="pre">exit_pass_ctx</span></code> of <code class="docutils literal notranslate"><span class="pre">PassTimingInstrument</span></code> is called.
Profiles are cleared so nothing is printed.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">cur_pass_ctx</span><span class="o">.</span><span class="n">override_instruments</span><span class="p">([])</span>
<span class="c1"># Uncomment the call to .render() to see a warning like:</span>
<span class="c1"># Warning: no passes have been profiled, did you enable pass profiling?</span>
<span class="c1"># profiles = timing_inst.render()</span>
</pre></div>
</div>
</div>
<div class="section" id="create-customized-instrument-class">
<h2>Create Customized Instrument Class<a class="headerlink" href="#create-customized-instrument-class" title="永久链接至标题">¶</a></h2>
<p>A customized instrument class can be created using the
<a class="reference internal" href="../../reference/api/python/ir.html#tvm.instrument.pass_instrument" title="tvm.instrument.pass_instrument"><code class="xref py py-func docutils literal notranslate"><span class="pre">tvm.instrument.pass_instrument()</span></code></a> decorator.</p>
<p>Let’s create an instrument class which calculates the change in number of
occurrences of each operator caused by each pass. We can look at <code class="docutils literal notranslate"><span class="pre">op.name</span></code> to
find the name of each operator. And we do this before and after passes to calculate the difference.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nd">@pass_instrument</span>
<span class="k">class</span> <span class="nc">RelayCallNodeDiffer</span><span class="p">:</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_op_diff</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="c1"># Passes can be nested.</span>
        <span class="c1"># Use stack to make sure we get correct before/after pairs.</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_op_cnt_before_stack</span> <span class="o">=</span> <span class="p">[]</span>

    <span class="k">def</span> <span class="nf">enter_pass_ctx</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_op_diff</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_op_cnt_before_stack</span> <span class="o">=</span> <span class="p">[]</span>

    <span class="k">def</span> <span class="nf">exit_pass_ctx</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_op_cnt_before_stack</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">,</span> <span class="s2">&quot;The stack is not empty. Something wrong.&quot;</span>

    <span class="k">def</span> <span class="nf">run_before_pass</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">mod</span><span class="p">,</span> <span class="n">info</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_op_cnt_before_stack</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">info</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_count_nodes</span><span class="p">(</span><span class="n">mod</span><span class="p">)))</span>

    <span class="k">def</span> <span class="nf">run_after_pass</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">mod</span><span class="p">,</span> <span class="n">info</span><span class="p">):</span>
        <span class="c1"># Pop out the latest recorded pass.</span>
        <span class="n">name_before</span><span class="p">,</span> <span class="n">op_to_cnt_before</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_op_cnt_before_stack</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
        <span class="k">assert</span> <span class="n">name_before</span> <span class="o">==</span> <span class="n">info</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="s2">&quot;name_before: </span><span class="si">{}</span><span class="s2">, info.name: </span><span class="si">{}</span><span class="s2"> doesn&#39;t match&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
            <span class="n">name_before</span><span class="p">,</span> <span class="n">info</span><span class="o">.</span><span class="n">name</span>
        <span class="p">)</span>
        <span class="n">cur_depth</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_op_cnt_before_stack</span><span class="p">)</span>
        <span class="n">op_to_cnt_after</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_count_nodes</span><span class="p">(</span><span class="n">mod</span><span class="p">)</span>
        <span class="n">op_diff</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_diff</span><span class="p">(</span><span class="n">op_to_cnt_after</span><span class="p">,</span> <span class="n">op_to_cnt_before</span><span class="p">)</span>
        <span class="c1"># only record passes causing differences.</span>
        <span class="k">if</span> <span class="n">op_diff</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">_op_diff</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">cur_depth</span><span class="p">,</span> <span class="n">info</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">op_diff</span><span class="p">))</span>

    <span class="k">def</span> <span class="nf">get_pass_to_op_diff</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        return [</span>
<span class="sd">          (depth, pass_name, {op_name: diff_num, ...}), ...</span>
<span class="sd">        ]</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_op_diff</span>

    <span class="nd">@staticmethod</span>
    <span class="k">def</span> <span class="nf">_count_nodes</span><span class="p">(</span><span class="n">mod</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Count the number of occurrences of each operator in the module&quot;&quot;&quot;</span>
        <span class="n">ret</span> <span class="o">=</span> <span class="p">{}</span>

        <span class="k">def</span> <span class="nf">visit</span><span class="p">(</span><span class="n">node</span><span class="p">):</span>
            <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">relay</span><span class="o">.</span><span class="n">expr</span><span class="o">.</span><span class="n">Call</span><span class="p">):</span>
                <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">op</span><span class="p">,</span> <span class="s2">&quot;name&quot;</span><span class="p">):</span>
                    <span class="n">op_name</span> <span class="o">=</span> <span class="n">node</span><span class="o">.</span><span class="n">op</span><span class="o">.</span><span class="n">name</span>
                <span class="k">else</span><span class="p">:</span>
                    <span class="c1"># Some CallNode may not have &#39;name&#39; such as relay.Function</span>
                    <span class="k">return</span>
                <span class="n">ret</span><span class="p">[</span><span class="n">op_name</span><span class="p">]</span> <span class="o">=</span> <span class="n">ret</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">op_name</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span>

        <span class="n">relay</span><span class="o">.</span><span class="n">analysis</span><span class="o">.</span><span class="n">post_order_visit</span><span class="p">(</span><span class="n">mod</span><span class="p">[</span><span class="s2">&quot;main&quot;</span><span class="p">],</span> <span class="n">visit</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">ret</span>

    <span class="nd">@staticmethod</span>
    <span class="k">def</span> <span class="nf">_diff</span><span class="p">(</span><span class="n">d_after</span><span class="p">,</span> <span class="n">d_before</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Calculate the difference of two dictionary along their keys.</span>
<span class="sd">        The result is values in d_after minus values in d_before.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">ret</span> <span class="o">=</span> <span class="p">{}</span>
        <span class="n">key_after</span><span class="p">,</span> <span class="n">key_before</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">d_after</span><span class="p">),</span> <span class="nb">set</span><span class="p">(</span><span class="n">d_before</span><span class="p">)</span>
        <span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="n">key_before</span> <span class="o">&amp;</span> <span class="n">key_after</span><span class="p">:</span>
            <span class="n">tmp</span> <span class="o">=</span> <span class="n">d_after</span><span class="p">[</span><span class="n">k</span><span class="p">]</span> <span class="o">-</span> <span class="n">d_before</span><span class="p">[</span><span class="n">k</span><span class="p">]</span>
            <span class="k">if</span> <span class="n">tmp</span><span class="p">:</span>
                <span class="n">ret</span><span class="p">[</span><span class="n">k</span><span class="p">]</span> <span class="o">=</span> <span class="n">d_after</span><span class="p">[</span><span class="n">k</span><span class="p">]</span> <span class="o">-</span> <span class="n">d_before</span><span class="p">[</span><span class="n">k</span><span class="p">]</span>
        <span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="n">key_after</span> <span class="o">-</span> <span class="n">key_before</span><span class="p">:</span>
            <span class="n">ret</span><span class="p">[</span><span class="n">k</span><span class="p">]</span> <span class="o">=</span> <span class="n">d_after</span><span class="p">[</span><span class="n">k</span><span class="p">]</span>
        <span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="n">key_before</span> <span class="o">-</span> <span class="n">key_after</span><span class="p">:</span>
            <span class="n">ret</span><span class="p">[</span><span class="n">k</span><span class="p">]</span> <span class="o">=</span> <span class="o">-</span><span class="n">d_before</span><span class="p">[</span><span class="n">k</span><span class="p">]</span>
        <span class="k">return</span> <span class="n">ret</span>
</pre></div>
</div>
</div>
<div class="section" id="apply-passes-and-multiple-instrument-classes">
<h2>Apply Passes and Multiple Instrument Classes<a class="headerlink" href="#apply-passes-and-multiple-instrument-classes" title="永久链接至标题">¶</a></h2>
<p>We can use multiple instrument classes in a <code class="docutils literal notranslate"><span class="pre">PassContext</span></code>.
However, it should be noted that instrument methods are executed sequentially,
obeying the order of <code class="docutils literal notranslate"><span class="pre">instruments</span></code> argument.
So for instrument classes like <code class="docutils literal notranslate"><span class="pre">PassTimingInstrument</span></code>, it is inevitable to
count-up the execution time of other instrument classes to the final
profile result.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">call_node_inst</span> <span class="o">=</span> <span class="n">RelayCallNodeDiffer</span><span class="p">()</span>
<span class="n">desired_layouts</span> <span class="o">=</span> <span class="p">{</span>
    <span class="s2">&quot;nn.conv2d&quot;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&quot;NHWC&quot;</span><span class="p">,</span> <span class="s2">&quot;HWIO&quot;</span><span class="p">],</span>
<span class="p">}</span>
<span class="n">pass_seq</span> <span class="o">=</span> <span class="n">tvm</span><span class="o">.</span><span class="n">transform</span><span class="o">.</span><span class="n">Sequential</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="n">relay</span><span class="o">.</span><span class="n">transform</span><span class="o">.</span><span class="n">FoldConstant</span><span class="p">(),</span>
        <span class="n">relay</span><span class="o">.</span><span class="n">transform</span><span class="o">.</span><span class="n">ConvertLayout</span><span class="p">(</span><span class="n">desired_layouts</span><span class="p">),</span>
        <span class="n">relay</span><span class="o">.</span><span class="n">transform</span><span class="o">.</span><span class="n">FoldConstant</span><span class="p">(),</span>
    <span class="p">]</span>
<span class="p">)</span>
<span class="n">relay_mod</span><span class="p">[</span><span class="s2">&quot;main&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">bind_params_by_name</span><span class="p">(</span><span class="n">relay_mod</span><span class="p">[</span><span class="s2">&quot;main&quot;</span><span class="p">],</span> <span class="n">relay_params</span><span class="p">)</span>
<span class="c1"># timing_inst is put after call_node_inst.</span>
<span class="c1"># So the execution time of ``call_node.inst.run_after_pass()`` is also counted.</span>
<span class="k">with</span> <span class="n">tvm</span><span class="o">.</span><span class="n">transform</span><span class="o">.</span><span class="n">PassContext</span><span class="p">(</span><span class="n">opt_level</span><span class="o">=</span><span class="mi">3</span><span class="p">,</span> <span class="n">instruments</span><span class="o">=</span><span class="p">[</span><span class="n">call_node_inst</span><span class="p">,</span> <span class="n">timing_inst</span><span class="p">]):</span>
    <span class="n">relay_mod</span> <span class="o">=</span> <span class="n">pass_seq</span><span class="p">(</span><span class="n">relay_mod</span><span class="p">)</span>
    <span class="n">profiles</span> <span class="o">=</span> <span class="n">timing_inst</span><span class="o">.</span><span class="n">render</span><span class="p">()</span>
<span class="c1"># Uncomment the next line to see timing-profile results.</span>
<span class="c1"># print(profiles)</span>
</pre></div>
</div>
<p>We can see how many CallNode increase/decrease per op type.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">pprint</span> <span class="k">import</span> <span class="n">pprint</span>

<span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Printing the change in number of occurrences of each operator caused by each pass...&quot;</span><span class="p">)</span>
<span class="n">pprint</span><span class="p">(</span><span class="n">call_node_inst</span><span class="o">.</span><span class="n">get_pass_to_op_diff</span><span class="p">())</span>
</pre></div>
</div>
<p class="sphx-glr-script-out">输出:</p>
<div class="sphx-glr-script-out highlight-none notranslate"><div class="highlight"><pre><span></span>Printing the change in number of occurrences of each operator caused by each pass...
[(1, &#39;CanonicalizeOps&#39;, {&#39;add&#39;: 1, &#39;nn.bias_add&#39;: -1}),
 (1, &#39;ConvertLayout&#39;, {&#39;expand_dims&#39;: 1, &#39;layout_transform&#39;: 23}),
 (1, &#39;FoldConstant&#39;, {&#39;expand_dims&#39;: -1, &#39;layout_transform&#39;: -21}),
 (0, &#39;sequential&#39;, {&#39;add&#39;: 1, &#39;layout_transform&#39;: 2, &#39;nn.bias_add&#39;: -1})]
</pre></div>
</div>
</div>
<div class="section" id="exception-handling">
<h2>Exception Handling<a class="headerlink" href="#exception-handling" title="永久链接至标题">¶</a></h2>
<p>Let’s see what happens if an exception occurs in a method of a <code class="docutils literal notranslate"><span class="pre">PassInstrument</span></code>.</p>
<p>Define <code class="docutils literal notranslate"><span class="pre">PassInstrument</span></code> classes which raise exceptions in enter/exit <code class="docutils literal notranslate"><span class="pre">PassContext</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">PassExampleBase</span><span class="p">:</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_name</span> <span class="o">=</span> <span class="n">name</span>

    <span class="k">def</span> <span class="nf">enter_pass_ctx</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">print</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="p">,</span> <span class="s2">&quot;enter_pass_ctx&quot;</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">exit_pass_ctx</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">print</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="p">,</span> <span class="s2">&quot;exit_pass_ctx&quot;</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">should_run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">mod</span><span class="p">,</span> <span class="n">info</span><span class="p">):</span>
        <span class="nb">print</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="p">,</span> <span class="s2">&quot;should_run&quot;</span><span class="p">)</span>
        <span class="k">return</span> <span class="kc">True</span>

    <span class="k">def</span> <span class="nf">run_before_pass</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">mod</span><span class="p">,</span> <span class="n">pass_info</span><span class="p">):</span>
        <span class="nb">print</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="p">,</span> <span class="s2">&quot;run_before_pass&quot;</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">run_after_pass</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">mod</span><span class="p">,</span> <span class="n">pass_info</span><span class="p">):</span>
        <span class="nb">print</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="p">,</span> <span class="s2">&quot;run_after_pass&quot;</span><span class="p">)</span>


<span class="nd">@pass_instrument</span>
<span class="k">class</span> <span class="nc">PassFine</span><span class="p">(</span><span class="n">PassExampleBase</span><span class="p">):</span>
    <span class="k">pass</span>


<span class="nd">@pass_instrument</span>
<span class="k">class</span> <span class="nc">PassBadEnterCtx</span><span class="p">(</span><span class="n">PassExampleBase</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">enter_pass_ctx</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">print</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="p">,</span> <span class="s2">&quot;bad enter_pass_ctx!!!&quot;</span><span class="p">)</span>
        <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2"> bad enter_pass_ctx&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="p">))</span>


<span class="nd">@pass_instrument</span>
<span class="k">class</span> <span class="nc">PassBadExitCtx</span><span class="p">(</span><span class="n">PassExampleBase</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">exit_pass_ctx</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">print</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="p">,</span> <span class="s2">&quot;bad exit_pass_ctx!!!&quot;</span><span class="p">)</span>
        <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2"> bad exit_pass_ctx&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="p">))</span>
</pre></div>
</div>
<p>If an exception occurs in <code class="docutils literal notranslate"><span class="pre">enter_pass_ctx</span></code>, <code class="docutils literal notranslate"><span class="pre">PassContext</span></code> will disable the pass
instrumentation. And it will run the <code class="docutils literal notranslate"><span class="pre">exit_pass_ctx</span></code> of each <code class="docutils literal notranslate"><span class="pre">PassInstrument</span></code>
which successfully finished <code class="docutils literal notranslate"><span class="pre">enter_pass_ctx</span></code>.</p>
<p>In following example, we can see <code class="docutils literal notranslate"><span class="pre">exit_pass_ctx</span></code> of <cite>PassFine_0</cite> is executed after exception.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">demo_ctx</span> <span class="o">=</span> <span class="n">tvm</span><span class="o">.</span><span class="n">transform</span><span class="o">.</span><span class="n">PassContext</span><span class="p">(</span>
    <span class="n">instruments</span><span class="o">=</span><span class="p">[</span>
        <span class="n">PassFine</span><span class="p">(</span><span class="s2">&quot;PassFine_0&quot;</span><span class="p">),</span>
        <span class="n">PassBadEnterCtx</span><span class="p">(</span><span class="s2">&quot;PassBadEnterCtx&quot;</span><span class="p">),</span>
        <span class="n">PassFine</span><span class="p">(</span><span class="s2">&quot;PassFine_1&quot;</span><span class="p">),</span>
    <span class="p">]</span>
<span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
    <span class="k">with</span> <span class="n">demo_ctx</span><span class="p">:</span>
        <span class="n">relay_mod</span> <span class="o">=</span> <span class="n">relay</span><span class="o">.</span><span class="n">transform</span><span class="o">.</span><span class="n">InferType</span><span class="p">()(</span><span class="n">relay_mod</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">ValueError</span> <span class="k">as</span> <span class="n">ex</span><span class="p">:</span>
    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Catching&quot;</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">ex</span><span class="p">)</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
</pre></div>
</div>
<p class="sphx-glr-script-out">输出:</p>
<div class="sphx-glr-script-out highlight-none notranslate"><div class="highlight"><pre><span></span>PassFine_0 enter_pass_ctx
PassBadEnterCtx bad enter_pass_ctx!!!
PassFine_0 exit_pass_ctx
Catching ValueError: PassBadEnterCtx bad enter_pass_ctx
</pre></div>
</div>
<p>Exceptions in <code class="docutils literal notranslate"><span class="pre">PassInstrument</span></code> instances cause all instruments of the current <code class="docutils literal notranslate"><span class="pre">PassContext</span></code>
to be cleared, so nothing is printed when <code class="docutils literal notranslate"><span class="pre">override_instruments</span></code> is called.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">demo_ctx</span><span class="o">.</span><span class="n">override_instruments</span><span class="p">([])</span>  <span class="c1"># no PassFine_0 exit_pass_ctx printed....etc</span>
</pre></div>
</div>
<p>If an exception occurs in <code class="docutils literal notranslate"><span class="pre">exit_pass_ctx</span></code>, then the pass instrument is disabled.
Then exception is propagated. That means <code class="docutils literal notranslate"><span class="pre">PassInstrument</span></code> instances registered
after the one throwing the exception do not execute <code class="docutils literal notranslate"><span class="pre">exit_pass_ctx</span></code>.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">demo_ctx</span> <span class="o">=</span> <span class="n">tvm</span><span class="o">.</span><span class="n">transform</span><span class="o">.</span><span class="n">PassContext</span><span class="p">(</span>
    <span class="n">instruments</span><span class="o">=</span><span class="p">[</span>
        <span class="n">PassFine</span><span class="p">(</span><span class="s2">&quot;PassFine_0&quot;</span><span class="p">),</span>
        <span class="n">PassBadExitCtx</span><span class="p">(</span><span class="s2">&quot;PassBadExitCtx&quot;</span><span class="p">),</span>
        <span class="n">PassFine</span><span class="p">(</span><span class="s2">&quot;PassFine_1&quot;</span><span class="p">),</span>
    <span class="p">]</span>
<span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
    <span class="c1"># PassFine_1 execute enter_pass_ctx, but not exit_pass_ctx.</span>
    <span class="k">with</span> <span class="n">demo_ctx</span><span class="p">:</span>
        <span class="n">relay_mod</span> <span class="o">=</span> <span class="n">relay</span><span class="o">.</span><span class="n">transform</span><span class="o">.</span><span class="n">InferType</span><span class="p">()(</span><span class="n">relay_mod</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">ValueError</span> <span class="k">as</span> <span class="n">ex</span><span class="p">:</span>
    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Catching&quot;</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">ex</span><span class="p">)</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
</pre></div>
</div>
<p class="sphx-glr-script-out">输出:</p>
<div class="sphx-glr-script-out highlight-none notranslate"><div class="highlight"><pre><span></span>PassFine_0 enter_pass_ctx
PassBadExitCtx enter_pass_ctx
PassFine_1 enter_pass_ctx
PassFine_0 should_run
PassBadExitCtx should_run
PassFine_1 should_run
PassFine_0 run_before_pass
PassBadExitCtx run_before_pass
PassFine_1 run_before_pass
PassFine_0 run_after_pass
PassBadExitCtx run_after_pass
PassFine_1 run_after_pass
PassFine_0 exit_pass_ctx
PassBadExitCtx bad exit_pass_ctx!!!
Catching ValueError: PassBadExitCtx bad exit_pass_ctx
</pre></div>
</div>
<p>Exceptions occured in <code class="docutils literal notranslate"><span class="pre">should_run</span></code>, <code class="docutils literal notranslate"><span class="pre">run_before_pass</span></code>, <code class="docutils literal notranslate"><span class="pre">run_after_pass</span></code>
are not handled explicitly – we rely on the context manager (the <code class="docutils literal notranslate"><span class="pre">with</span></code> syntax)
to exit <code class="docutils literal notranslate"><span class="pre">PassContext</span></code> safely.</p>
<p>We use <code class="docutils literal notranslate"><span class="pre">run_before_pass</span></code> as an example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nd">@pass_instrument</span>
<span class="k">class</span> <span class="nc">PassBadRunBefore</span><span class="p">(</span><span class="n">PassExampleBase</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">run_before_pass</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">mod</span><span class="p">,</span> <span class="n">pass_info</span><span class="p">):</span>
        <span class="nb">print</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="p">,</span> <span class="s2">&quot;bad run_before_pass!!!&quot;</span><span class="p">)</span>
        <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2"> bad run_before_pass&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="p">))</span>


<span class="n">demo_ctx</span> <span class="o">=</span> <span class="n">tvm</span><span class="o">.</span><span class="n">transform</span><span class="o">.</span><span class="n">PassContext</span><span class="p">(</span>
    <span class="n">instruments</span><span class="o">=</span><span class="p">[</span>
        <span class="n">PassFine</span><span class="p">(</span><span class="s2">&quot;PassFine_0&quot;</span><span class="p">),</span>
        <span class="n">PassBadRunBefore</span><span class="p">(</span><span class="s2">&quot;PassBadRunBefore&quot;</span><span class="p">),</span>
        <span class="n">PassFine</span><span class="p">(</span><span class="s2">&quot;PassFine_1&quot;</span><span class="p">),</span>
    <span class="p">]</span>
<span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
    <span class="c1"># All exit_pass_ctx are called.</span>
    <span class="k">with</span> <span class="n">demo_ctx</span><span class="p">:</span>
        <span class="n">relay_mod</span> <span class="o">=</span> <span class="n">relay</span><span class="o">.</span><span class="n">transform</span><span class="o">.</span><span class="n">InferType</span><span class="p">()(</span><span class="n">relay_mod</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">ValueError</span> <span class="k">as</span> <span class="n">ex</span><span class="p">:</span>
    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Catching&quot;</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">ex</span><span class="p">)</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
</pre></div>
</div>
<p class="sphx-glr-script-out">输出:</p>
<div class="sphx-glr-script-out highlight-none notranslate"><div class="highlight"><pre><span></span>PassFine_0 enter_pass_ctx
PassBadRunBefore enter_pass_ctx
PassFine_1 enter_pass_ctx
PassFine_0 should_run
PassBadRunBefore should_run
PassFine_1 should_run
PassFine_0 run_before_pass
PassBadRunBefore bad run_before_pass!!!
PassFine_0 exit_pass_ctx
PassBadRunBefore exit_pass_ctx
PassFine_1 exit_pass_ctx
Catching ValueError: PassBadRunBefore bad run_before_pass
</pre></div>
</div>
<p>Also note that pass instrumentation is not disable. So if we call
<code class="docutils literal notranslate"><span class="pre">override_instruments</span></code>, the <code class="docutils literal notranslate"><span class="pre">exit_pass_ctx</span></code> of old registered <code class="docutils literal notranslate"><span class="pre">PassInstrument</span></code>
is called.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">demo_ctx</span><span class="o">.</span><span class="n">override_instruments</span><span class="p">([])</span>
</pre></div>
</div>
<p class="sphx-glr-script-out">输出:</p>
<div class="sphx-glr-script-out highlight-none notranslate"><div class="highlight"><pre><span></span>PassFine_0 exit_pass_ctx
PassBadRunBefore exit_pass_ctx
PassFine_1 exit_pass_ctx
</pre></div>
</div>
<p>If we don’t wrap pass execution with <code class="docutils literal notranslate"><span class="pre">with</span></code> syntax, <code class="docutils literal notranslate"><span class="pre">exit_pass_ctx</span></code> is not
called. Let try this with current <code class="docutils literal notranslate"><span class="pre">PassContext</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">cur_pass_ctx</span> <span class="o">=</span> <span class="n">tvm</span><span class="o">.</span><span class="n">transform</span><span class="o">.</span><span class="n">PassContext</span><span class="o">.</span><span class="n">current</span><span class="p">()</span>
<span class="n">cur_pass_ctx</span><span class="o">.</span><span class="n">override_instruments</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="n">PassFine</span><span class="p">(</span><span class="s2">&quot;PassFine_0&quot;</span><span class="p">),</span>
        <span class="n">PassBadRunBefore</span><span class="p">(</span><span class="s2">&quot;PassBadRunBefore&quot;</span><span class="p">),</span>
        <span class="n">PassFine</span><span class="p">(</span><span class="s2">&quot;PassFine_1&quot;</span><span class="p">),</span>
    <span class="p">]</span>
<span class="p">)</span>
</pre></div>
</div>
<p class="sphx-glr-script-out">输出:</p>
<div class="sphx-glr-script-out highlight-none notranslate"><div class="highlight"><pre><span></span>PassFine_0 enter_pass_ctx
PassBadRunBefore enter_pass_ctx
PassFine_1 enter_pass_ctx
</pre></div>
</div>
<p>Then call passes. <code class="docutils literal notranslate"><span class="pre">exit_pass_ctx</span></code> is not executed after the exception,
as expectation.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
    <span class="c1"># No ``exit_pass_ctx`` got executed.</span>
    <span class="n">relay_mod</span> <span class="o">=</span> <span class="n">relay</span><span class="o">.</span><span class="n">transform</span><span class="o">.</span><span class="n">InferType</span><span class="p">()(</span><span class="n">relay_mod</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">ValueError</span> <span class="k">as</span> <span class="n">ex</span><span class="p">:</span>
    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Catching&quot;</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">ex</span><span class="p">)</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
</pre></div>
</div>
<p class="sphx-glr-script-out">输出:</p>
<div class="sphx-glr-script-out highlight-none notranslate"><div class="highlight"><pre><span></span>PassFine_0 should_run
PassBadRunBefore should_run
PassFine_1 should_run
PassFine_0 run_before_pass
PassBadRunBefore bad run_before_pass!!!
Catching ValueError: PassBadRunBefore bad run_before_pass
</pre></div>
</div>
<p>Clear instruments.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">cur_pass_ctx</span><span class="o">.</span><span class="n">override_instruments</span><span class="p">([])</span>
</pre></div>
</div>
<p class="sphx-glr-script-out">输出:</p>
<div class="sphx-glr-script-out highlight-none notranslate"><div class="highlight"><pre><span></span>PassFine_0 exit_pass_ctx
PassBadRunBefore exit_pass_ctx
PassFine_1 exit_pass_ctx
</pre></div>
</div>
<div class="sphx-glr-footer class sphx-glr-footer-example docutils container" id="sphx-glr-download-how-to-extend-tvm-use-pass-instrument-py">
<div class="sphx-glr-download docutils container">
<p><a class="reference download internal" download="" href="../../_downloads/d0a1817b910da958b41d88afe4d4952d/use_pass_instrument.py"><code class="xref download docutils literal notranslate"><span class="pre">Download</span> <span class="pre">Python</span> <span class="pre">source</span> <span class="pre">code:</span> <span class="pre">use_pass_instrument.py</span></code></a></p>
</div>
<div class="sphx-glr-download docutils container">
<p><a class="reference download internal" download="" href="../../_downloads/f6ff0fbc61d45d2cc0f53ebbf11a5fb5/use_pass_instrument.ipynb"><code class="xref download docutils literal notranslate"><span class="pre">Download</span> <span class="pre">Jupyter</span> <span class="pre">notebook:</span> <span class="pre">use_pass_instrument.ipynb</span></code></a></p>
</div>
</div>
<p class="sphx-glr-signature"><a class="reference external" href="https://sphinx-gallery.github.io">Gallery generated by Sphinx-Gallery</a></p>
</div>
</div>


           </div>
           
          </div>
          

<footer>

    <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
      
        <a href="bring_your_own_datatypes.html" class="btn btn-neutral float-right" title="Bring Your Own Datatypes to TVM" accesskey="n" rel="next">下一个 <span class="fa fa-arrow-circle-right"></span></a>
      
      
        <a href="use_pass_infra.html" class="btn btn-neutral float-left" title="How to Use TVM Pass Infra" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left"></span> 上一个</a>
      
    </div>

<div id="button" class="backtop"><img src="../../_static//img/right.svg" alt="backtop"/> </div>
<section class="footerSec">
    <div class="footerHeader">
      <ul class="d-flex align-md-items-center justify-content-between flex-column flex-md-row">
        <li class="copywrite d-flex align-items-center">
          <h5 id="copy-right-info">© 2020 Apache Software Foundation | All right reserved</h5>
        </li>
      </ul>

    </div>

    <ul>
      <li class="footernote">Copyright © 2020 The Apache Software Foundation. Apache TVM, Apache, the Apache feather, and the Apache TVM project logo are either trademarks or registered trademarks of the Apache Software Foundation.</li>
    </ul>

</section>
</footer>
        </div>
      </div>

    </section>

  </div>
  

    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>

  </body>
  <script type="text/javascript">
      jQuery(function () {
          SphinxRtdTheme.Navigation.enable(true);
      });
  </script>

  
  
    
    <!-- Theme Analytics -->
    <script>
    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
      (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
      m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
    })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

    ga('create', 'UA-75982049-2', 'auto');
    ga('send', 'pageview');
    </script>

    
   

</body>
</html>